package tech.anzhen.simple.rpc.support.rest;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.Query;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;

public class RestUtils {

    public static final String X_REST_AUTH_ID = "X-Rest-Auth-ID";

    public static final String X_REST_SIGN = "X-Rest-Sign";

    public static final String X_REST_TRACER = "X-Rest-Tracer";

    public static String javaNameToRest(String s) {
        if (s.isEmpty()) {
            return "";
        }
        s = s.substring(0, 1).toUpperCase() + s.substring(1);

        String r = s.replaceAll("([A-Z][^A-Z]+)", "$1-");
        if (r.isEmpty()) {
            return "";
        }

        return r.toLowerCase().substring(0, r.length() - 1);
    }

    public static String pathAppend(String root, String sub) {
        if (root.endsWith("/")) {
            if (sub.startsWith("/")) {
                return root + sub.substring(1);
            } else {
                return root + sub;
            }
        } else {
            if (sub.startsWith("/")) {
                return root + sub;
            } else {
                return root + "/" + sub;
            }
        }
    }

    public static Gson buildGson() {
        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Date.class, new DateTypeAdapter());
        return builder.create();
    }

    private static class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {

        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(src.getTime());
        }

        @Override
        public Date deserialize(JsonElement json, Type type, JsonDeserializationContext cxt) {
            try {
                return new Date(json.getAsLong());
            } catch (Exception e) {
                try {
                    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(json.getAsString());
                } catch (ParseException e1) {
                    try {
                        return new SimpleDateFormat("yyyy-MM-dd").parse(json.getAsString());
                    } catch (ParseException e2) {
                        throw new RestException("无法转换为Date类型");
                    }
                }
            }
        }
    }

    public static String getServerPort() {
        try {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            Set<ObjectName> objs = mbs.queryNames(new ObjectName("*:type=Connector,*"),
                    Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
            String hostname = InetAddress.getLocalHost().getHostName();
            for (Iterator<ObjectName> i = objs.iterator(); i.hasNext(); ) {
                ObjectName obj = i.next();
                String port = obj.getKeyProperty("port");
                return String.valueOf(port);
            }
            return "";
        } catch (Exception e) {
            return "";
        }
    }
}
